package cn.net.mugui.net.udp;

import com.mugui.base.base.Autowired;
import com.mugui.base.base.Component;
import com.mugui.base.client.net.auto.AutoTask;
import com.mugui.base.client.net.base.Task;
import com.mugui.base.client.net.base.TaskInterface;
import com.mugui.base.util.Other;

import cn.hutool.core.thread.ThreadUtil;
import lombok.Setter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

/**
 * udp服务
 *
 * @author 木鬼
 */
@Component
@AutoTask
@Task()
public class UdpBaseServer implements TaskInterface {
	DatagramSocket socket = null;
	DatagramSocket test = null;
	@Autowired
	private UdpReceiveListener udpReceiveListener;

	public void init() {
		try {
			bind();
		} catch (Exception e) {
			System.exit(0);
		}
	}

	public void port(int port) {
		if (socket != null) {
			socket.disconnect();
			test.disconnect();
			socket.close();
			test.close();
		}
		try {
			socket = new DatagramSocket(port);
			test = new DatagramSocket(socket.getLocalPort() + 1);
		} catch (SocketException e) {
			throw new RuntimeException(e);
		}
		System.out.println("绑定地址为：" + socket.getLocalPort());
	}

	/**
	 * 发送
	 *
	 * @param data
	 * @throws IOException
	 * @author 木鬼
	 * @param socket
	 */
	public void send(DatagramSocket socket, DatagramPacket data) throws IOException {
		socket.send(data);
	}

	public void send(DatagramSocket socket, byte[] data, String host, int port) throws IOException {
		DatagramPacket datagramPacket = new DatagramPacket(data, data.length);
		datagramPacket.setAddress(InetAddress.getByName(host));
		datagramPacket.setPort(port);
		send(socket, datagramPacket);
	}

	@Override
	public void run() {
		ThreadUtil.execute(new Runnable() {//主服务

			@Override
			public void run() {
				DatagramPacket receive_data = new DatagramPacket(new byte[102400], 102400);
				while (true) {
					try {
						socket.receive(receive_data);
						udpReceiveListener.receive(socket, receive_data);
					} catch (Exception e) {
						e.printStackTrace();
						Other.sleep(1000);
					}
				}
			}
		});
		ThreadUtil.execute(new Runnable() {//测试服务
			@Override
			public void run() {
				DatagramPacket receive_data = new DatagramPacket(new byte[102400], 102400);
				while (true) {
					try {
						test.receive(receive_data);
						udpReceiveListener.receive(test, receive_data);
					} catch (Exception e) {
						e.printStackTrace();
						Other.sleep(1000);
					}
				}
			}
		});
	}

	@Setter
	private static int default_port = 8023;

	private void bind() {
		try {
			port(default_port);
		} catch (Exception e) {
			e.printStackTrace();
			try {
				port(0);
			} catch (Exception e1) {
				throw new RuntimeException(e1);
			}
		}
	}

	public interface ReceiveListener {

		/**
		 * 通用的包接收处理器
		 * 
		 * @param socket
		 */
		void receive(DatagramSocket socket, DatagramPacket server);
	}

	/**
	 * 得到主要端口网络
	 * 
	 * @return
	 */
	public DatagramSocket base() {
		return socket;
	}

	/**
	 * 得到测试端口网络
	 * 
	 * @return
	 */
	public DatagramSocket test() {
		return test;
	}

}
